#include "RecvMsg.h"
#include "chip_type.h"
#include <memory.h>
#include <string.h>
#ifdef WIN32
#include <Winsock2.h>
#else
#include <arpa/inet.h>
#endif

CRecvMsg::CRecvMsg()
	:buffer(0), bodyLen(0)
{
	buffer = new char[sizeof(PKGHeader) + INIT_BODYLEN];
	maxBodySize = INIT_BODYLEN;
}


CRecvMsg::~CRecvMsg()
{
	if (buffer)
		delete[] buffer;
	buffer = 0;
	maxBodySize = 0;
}

char * CRecvMsg::GetHead()
{
	return buffer;
}

int CRecvMsg::GetHeadLen()
{
	if (!buffer)
		return 0;

	return sizeof(PKGHeader);
}

char * CRecvMsg::GetBody()
{
	if (!buffer)
		return NULL;

	return buffer + sizeof(PKGHeader);
}

int CRecvMsg::GetBodyLen()
{
	if (!buffer)
		return 0;

	return bodyLen;
}

bool CRecvMsg::decode_header()
{
	PKGHeader* pHead = (PKGHeader*)GetHead();
	int nLength = ntohl(pHead->length);
	if (nLength > maxBodySize)
	{
		if (buffer)
		{
			delete[] buffer;
			buffer = NULL;
			maxBodySize = 0;
		}
		buffer = new char[sizeof(PKGHeader) + nLength];

		if (buffer){
			memcpy(buffer, (char*)pHead, sizeof(PKGHeader));
			maxBodySize = nLength;

		}
		else
			return false;
	}

	bodyLen = nLength;
	return true;
}

bool CRecvMsg::decode_body()
{
	if (INetChecksum(buffer, GetHeadLen() + GetBodyLen()) != 0)
		return false;
	PKGHeader* pHead = (PKGHeader*)GetHead();

	pHead->bootcode   = ntohs(pHead->bootcode);
	pHead->checksum   = ntohs(pHead->checksum);
	pHead->type       = ntohs(pHead->type);
	pHead->attrs      = ntohs(pHead->attrs);
	pHead->length     = ntohl(pHead->length);
	pHead->seq_id     = ntohl(pHead->seq_id);
	pHead->error_code = ntohs(pHead->error_code);

	return true;
}
